#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/sem.h>
#include <sys/ipc.h>
#include <inttypes.h>
#include <time.h>
#include <genrand.h>
#include <hexstr.h>
#include <logbase.h>

struct wgDataStc
{
    uint8_t buf[10];
    uint8_t bsize;
    uint8_t even;
    uint8_t odd;
};

static uint8_t calcWgBit1Sum(uint8_t *wgdata, uint8_t bbegin, uint8_t bend)
{
    uint8_t i;
    uint8_t tmpv = 0;
    for (i = bbegin; i < bend; i++)
    {
        if (wgdata[i / 8] & (1 << (7 - (i % 8))))
        {
            tmpv++;
        }
    }
    return tmpv & 0x01;
}

static int calcWgEo(struct wgDataStc *wgd)
{
    switch (wgd->bsize)
    {
    case 26:
    {
        if (calcWgBit1Sum(wgd->buf, 0, 12))
        {
            wgd->even = 0x80;
        }
        else
        {
            wgd->even = 0x00;
        }
        if (calcWgBit1Sum(wgd->buf, 12, 24))
        {
            wgd->odd = 0;
        }
        else
        {
            wgd->odd = 0x80;
        }
        break;
    }
    case 34:
    {
        if (calcWgBit1Sum(wgd->buf, 0, 16))
        {
            wgd->even = 0x80;
        }
        else
        {
            wgd->even = 0x00;
        }
        if (calcWgBit1Sum(wgd->buf, 16, 32))
        {
            wgd->odd = 0;
        }
        else
        {
            wgd->odd = 0x80;
        }
        break;
    }
    case 44:
    {
        wgd->even = 0;
        wgd->even ^= wgd->buf[0];
        wgd->even ^= wgd->buf[1];
        wgd->even ^= wgd->buf[2];
        wgd->even ^= wgd->buf[3];
        wgd->even ^= wgd->buf[4];
        wgd->even <<= 4;
        break;
    }
    default:
    {
        logerrorc("%d", wgd->bsize);
        return -1;
    }
    }
    return 0;
}

static void sendWgChar(uint8_t wgval, uint8_t bitlen)
{
	uint8_t i;
	for(i = 0; i < bitlen; i++)
	{
		// WG_DATA0 = 1;
		// WG_DATA1 = 1;
		if (wgval & 0x80)
		{
			// WG_DATA1 = 0;
			// Delay_50us(8);
			// WG_DATA1 = 1;
		}
		else
		{
			// WG_DATA0 = 0;
			// Delay_50us(8);
			// WG_DATA0 = 1;
		}
        // wgval <<= 1;
		// Delay_1ms(2);
	}
}

int sndWgBuf(struct wgDataStc *wgd)
{
    if(calcWgEo(wgd) < 0)
    {
        logerrorc("%d", wgd->bsize);
        return -1;
    }
    switch (wgd->bsize)
    {
    case 26:
    {
        sendWgChar(wgd->even, 1);
        sendWgChar(wgd->buf[0], 8);
        sendWgChar(wgd->buf[1], 8);
        sendWgChar(wgd->buf[2], 8);
        sendWgChar(wgd->odd, 1);
        break;
    }
    case 34:
    {
        sendWgChar(wgd->even, 1);
        sendWgChar(wgd->buf[0], 8);
        sendWgChar(wgd->buf[1], 8);
        sendWgChar(wgd->buf[2], 8);
        sendWgChar(wgd->buf[3], 8);
        sendWgChar(wgd->odd, 1);
        break;
    }
    case 44:
    {
        sendWgChar(wgd->buf[0], 8);
        sendWgChar(wgd->buf[1], 8);
        sendWgChar(wgd->buf[2], 8);
        sendWgChar(wgd->buf[3], 8);
        sendWgChar(wgd->buf[4], 8);
        sendWgChar(wgd->even, 4);
        break;
    }
    default:
    {
        logerrorc("%d", wgd->bsize);
        return -1;
    }
    }
    return 0;
}



#define chkMaxSize 1
int main(int argsize, const char **args)
{
    struct wgDataStc tmpwg;
    genRandHexBuf((char *)tmpwg.buf, sizeof(tmpwg));
    {
        char tmpHexstr[sizeof(tmpwg.buf) * 2 + 1];
        cvtHex2str(tmpwg.buf, sizeof(tmpwg.buf), tmpHexstr, sizeof(tmpHexstr));
        logdebugc("%s", tmpHexstr);
    }
    logdebugc("bit print:");
    for (int i = 0; i < (int)sizeof(tmpwg.buf); i++)
    {
        for (int j = 7; j >= 0; j--)
        {
            if (tmpwg.buf[i] & (1 << j))
            {
                printf("1");
            }
            else
            {
                printf("0");
            }
        }
        printf(" ");
    }
    printf("\n");
    tmpwg.bsize = 26;
    calcWgEo(&tmpwg);
    logdebugc("wg26:e=0x%02x,o=0x%02x", tmpwg.even, tmpwg.odd);
    tmpwg.bsize = 34;
    calcWgEo(&tmpwg);
    logdebugc("wg34:e=0x%02x,o=0x%02x", tmpwg.even, tmpwg.odd);
    return 0;
}